using Lzfy_Refund_Service.Models;
using Lzfy_Refund_Service.Repositories;
using Microsoft.Extensions.Options;
using TaskStatus = Lzfy_Refund_Service.Models.PasswordTaskStatus;

namespace Lzfy_Refund_Service.Services
{
    /// <summary>
    /// 密码更新任务服务实现
    /// </summary>
    public class PasswordUpdateTaskService : IPasswordUpdateTaskService
    {
        private readonly IPasswordUpdateTaskRepository _taskRepository;
        private readonly IPatientRefundPasswordService _passwordService;
        private readonly IVerifyInfoService _verifyInfoService;
        private readonly ILogger<PasswordUpdateTaskService> _logger;
        private readonly PasswordUpdateTaskOptions _options;

        public PasswordUpdateTaskService(
            IPasswordUpdateTaskRepository taskRepository,
            IPatientRefundPasswordService passwordService,
            IVerifyInfoService verifyInfoService,
            ILogger<PasswordUpdateTaskService> logger,
            IOptions<PasswordUpdateTaskOptions> options)
        {
            _taskRepository = taskRepository;
            _passwordService = passwordService;
            _verifyInfoService = verifyInfoService;
            _logger = logger;
            _options = options.Value;
        }

        /// <summary>
        /// 创建密码更新任务
        /// </summary>
        public async Task<CreatePasswordUpdateTaskResponse> CreateTaskAsync(CreatePasswordUpdateTaskRequest request)
        {
            try
            {
                // 验证请求参数
                if (string.IsNullOrWhiteSpace(request.PatientId))
                {
                    return new CreatePasswordUpdateTaskResponse
                    {
                        Success = false,
                        Message = "患者ID不能为空"
                    };
                }

                if (string.IsNullOrWhiteSpace(request.VerifyCode))
                {
                    return new CreatePasswordUpdateTaskResponse
                    {
                        Success = false,
                        Message = "验证码不能为空"
                    };
                }

                if (string.IsNullOrWhiteSpace(request.RefundPassword))
                {
                    return new CreatePasswordUpdateTaskResponse
                    {
                        Success = false,
                        Message = "退费密码不能为空"
                    };
                }

                if (string.IsNullOrWhiteSpace(request.Modifier))
                {
                    return new CreatePasswordUpdateTaskResponse
                    {
                        Success = false,
                        Message = "修改者不能为空"
                    };
                }

                // 取消该患者之前的待执行任务
                var cancelledCount = await _taskRepository.CancelPendingTasksByPatientIdAsync(request.PatientId);
                if (cancelledCount > 0)
                {
                    _logger.LogInformation("取消患者 {PatientId} 的 {Count} 个待执行任务", request.PatientId, cancelledCount);
                }

                // 创建新任务
                var taskId = Guid.NewGuid().ToString();
                var scheduledTime = DateTime.Now.AddMinutes(_options.DelayMinutes);
                
                _logger.LogInformation("使用配置的延迟时间: {DelayMinutes} 分钟", _options.DelayMinutes);

                var task = new PasswordUpdateTask
                {
                    TaskId = taskId,
                    PatientId = request.PatientId,
                    VerifyCode = request.VerifyCode,
                    VerifyInfoId = request.VerifyInfoId,
                    RefundPassword = request.RefundPassword,
                    Modifier = request.Modifier,
                    ModifierCardType = request.ModifierCardType,
                    ModifierCardCode = request.ModifierCardCode,
                    ScheduledTime = scheduledTime,
                    CreatedTime = DateTime.Now,
                    Status = TaskStatus.Pending
                };

                await _taskRepository.CreateTaskAsync(task);

                _logger.LogInformation("创建密码更新任务成功，任务ID: {TaskId}, 患者ID: {PatientId}, 计划执行时间: {ScheduledTime}", 
                    taskId, request.PatientId, scheduledTime);

                return new CreatePasswordUpdateTaskResponse
                {
                    Success = true,
                    Message = "任务创建成功",
                    TaskId = taskId,
                    ScheduledTime = scheduledTime
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "创建密码更新任务失败，患者ID: {PatientId}", request.PatientId);
                return new CreatePasswordUpdateTaskResponse
                {
                    Success = false,
                    Message = $"创建任务失败: {ex.Message}"
                };
            }
        }

        /// <summary>
        /// 查询任务状态
        /// </summary>
        public async Task<QueryTaskStatusResponse> QueryTaskStatusAsync(QueryTaskStatusRequest request)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(request.TaskId))
                {
                    return new QueryTaskStatusResponse
                    {
                        Success = false,
                        Message = "任务ID不能为空"
                    };
                }

                var task = await _taskRepository.GetTaskByIdAsync(request.TaskId);
                if (task == null)
                {
                    return new QueryTaskStatusResponse
                    {
                        Success = false,
                        Message = "任务不存在"
                    };
                }

                return new QueryTaskStatusResponse
                {
                    Success = true,
                    Message = "查询成功",
                    Task = task
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "查询任务状态失败，任务ID: {TaskId}", request.TaskId);
                return new QueryTaskStatusResponse
                {
                    Success = false,
                    Message = $"查询失败: {ex.Message}"
                };
            }
        }

        /// <summary>
        /// 取消任务
        /// </summary>
        public async Task<CancelTaskResponse> CancelTaskAsync(CancelTaskRequest request)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(request.TaskId))
                {
                    return new CancelTaskResponse
                    {
                        Success = false,
                        Message = "任务ID不能为空"
                    };
                }

                var success = await _taskRepository.CancelTaskAsync(request.TaskId);
                if (success)
                {
                    _logger.LogInformation("取消任务成功，任务ID: {TaskId}", request.TaskId);
                    return new CancelTaskResponse
                    {
                        Success = true,
                        Message = "任务取消成功"
                    };
                }
                else
                {
                    return new CancelTaskResponse
                    {
                        Success = false,
                        Message = "任务取消失败，可能任务不存在或已执行"
                    };
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "取消任务失败，任务ID: {TaskId}", request.TaskId);
                return new CancelTaskResponse
                {
                    Success = false,
                    Message = $"取消任务失败: {ex.Message}"
                };
            }
        }

        /// <summary>
        /// 根据患者ID获取待执行的任务
        /// </summary>
        public async Task<List<PasswordUpdateTask>> GetPendingTasksByPatientIdAsync(string patientId)
        {
            try
            {
                return await _taskRepository.GetPendingTasksByPatientIdAsync(patientId);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取患者待执行任务失败，患者ID: {PatientId}", patientId);
                return new List<PasswordUpdateTask>();
            }
        }

        /// <summary>
        /// 执行密码更新任务
        /// </summary>
        public async Task<bool> ExecuteTaskAsync(PasswordUpdateTask task)
        {
            try
            {
                _logger.LogInformation("开始执行密码更新任务，任务ID: {TaskId}, 患者ID: {PatientId}", task.TaskId, task.PatientId);

                // 更新任务状态为执行中
                await _taskRepository.UpdateTaskStatusAsync(task.TaskId, TaskStatus.Executing, DateTime.Now);

                // 调用密码更新服务
                var updateRequest = new PatientRefundPasswordUpdateRequest
                {
                    PatientId = task.PatientId,
                    RefundPassword = task.RefundPassword,
                    Modifier = task.Modifier,
                    ModifierCardType = task.ModifierCardType,
                    ModifierCardCode = task.ModifierCardCode,
                    ModifyTime = DateTime.Now
                };

                var updateResponse = await _passwordService.UpdatePatientRefundPasswordAsync(updateRequest);

                if (updateResponse.Success)
                {
                    // 更新任务状态为已完成
                    await _taskRepository.UpdateTaskStatusAsync(task.TaskId, TaskStatus.Completed, DateTime.Now);
                    
                    // 软删除指定的验证码信息
                    try
                    {
                        if (task.VerifyInfoId.HasValue)
                        {
                            var result = await _verifyInfoService.SoftDeleteAsync(task.VerifyInfoId.Value, "System-PasswordUpdate");
                            if (result)
                            {
                                _logger.LogInformation("软删除验证码信息成功，验证码ID: {VerifyInfoId}, 验证码: {VerifyCode}, 患者ID: {PatientId}", 
                                    task.VerifyInfoId.Value, task.VerifyCode, task.PatientId);
                            }
                            else
                            {
                                _logger.LogWarning("软删除验证码信息失败，验证码ID: {VerifyInfoId}, 验证码: {VerifyCode}, 患者ID: {PatientId}", 
                                    task.VerifyInfoId.Value, task.VerifyCode, task.PatientId);
                            }
                        }
                        else
                        {
                            _logger.LogWarning("任务中未指定验证码ID，跳过软删除操作，验证码: {VerifyCode}, 患者ID: {PatientId}", task.VerifyCode, task.PatientId);
                        }
                    }
                    catch (Exception ex)
                    {
                        _logger.LogWarning(ex, "软删除验证码信息失败，验证码ID: {VerifyInfoId}, 验证码: {VerifyCode}, 患者ID: {PatientId}，但密码更新任务已成功", 
                            task.VerifyInfoId, task.VerifyCode, task.PatientId);
                    }
                    
                    _logger.LogInformation("密码更新任务执行成功，任务ID: {TaskId}, 患者ID: {PatientId}", task.TaskId, task.PatientId);
                    return true;
                }
                else
                {
                    // 增加重试次数
                    await _taskRepository.IncrementRetryCountAsync(task.TaskId, updateResponse.Message);
                    _logger.LogWarning("密码更新任务执行失败，任务ID: {TaskId}, 患者ID: {PatientId}, 错误: {Error}", 
                        task.TaskId, task.PatientId, updateResponse.Message);
                    return false;
                }
            }
            catch (Exception ex)
            {
                // 增加重试次数
                await _taskRepository.IncrementRetryCountAsync(task.TaskId, ex.Message);
                _logger.LogError(ex, "密码更新任务执行异常，任务ID: {TaskId}, 患者ID: {PatientId}", task.TaskId, task.PatientId);
                return false;
            }
        }

        /// <summary>
        /// 获取任务统计信息
        /// </summary>
        public async Task<Dictionary<string, int>> GetTaskStatisticsAsync()
        {
            try
            {
                return await _taskRepository.GetTaskStatisticsAsync();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取任务统计信息失败");
                return new Dictionary<string, int>();
            }
        }
    }
}